/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package genomemap.cef.command.listener;

import cef.command.Command;
import cef.command.listener.CommandOutputEvent;
import cef.command.listener.CommandOutputListener;
import cef.command.listener.CommandOutputListenerException;
import cef.command.listener.CommandPrintWriter;
import genomemap.cef.command.ComplData_Cmd;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * @author Susanta Tewari
 * @since Jun 12, 2011
 */
public class ProcessComplData_PW extends CommandPrintWriter {

    /**
     * Method description
     *
     *
     * @param cmdOutputEvent
     *
     * @throws CommandOutputListenerException
     */
    @Override
    public void receivedEventImpl(final CommandOutputEvent cmdOutputEvent)
            throws CommandOutputListenerException {


        // 1. get the command
        final ComplData_Cmd command = (ComplData_Cmd) cmdOutputEvent.getSource();


        // 2. get the assignments
        final Map<Integer, Map<String, Set<String>>> assignments = command.getAssignments();


        // 3. Create an XML element
        final Element element = createAssignmentXML(assignments);


        // 4. print the assignment XML element
        try {

            final OutputFormat format = OutputFormat.createPrettyPrint();
            final XMLWriter writer    = new XMLWriter(getPrintWriter(), format);

            writer.write(element);


            // XMLWriter does not end with a line-break; fore one here
            getPrintWriter().println();

        } catch (IOException ex) {
            throw new CommandOutputListenerException("Error printing results", ex);
        }


        // 5. Report the input-assignment-genes not found in the organism data
        final Set<String> genes_not_found = command.getGenesNotFound();

        getPrintWriter().println("Input-assignment-genes not found in organism data." + " Count: "
                                 + genes_not_found.size() + " Genes: " + genes_not_found);


        // 6. Report the input-assignment-genes for which the assignment clones are
        // not found in the organism data
        final Set<String> genes_with_empty_clones = command.getGenesWithEmptyClones();

        getPrintWriter().println("Input-assignment-genes without clones in organism data."
                                 + " Count: " + genes_with_empty_clones.size() + " Genes: "
                                 + genes_with_empty_clones);


        // 7. Report the total number of assignment
        getPrintWriter().println("Total assignment count: " + command.getTotalAssignmentCount());
    }

    /**
     * Method description
     *
     *
     * @return
     */
    @Override
    public Class<? extends Command> getTargetCommandClass() {
        return ComplData_Cmd.class;
    }

    /**
     * Method description
     *
     *
     * @param assignments
     *
     * @return
     */
    private Element createAssignmentXML(final Map<Integer, Map<String, Set<String>>> assignments) {

        final Element assignments_element = DocumentHelper.createElement("assignments");

        for (final Integer linkageGroup : assignments.keySet()) {


            // ch element with id attribute
            final Element ch_element = DocumentHelper.createElement("ch");

            ch_element.addAttribute("id", linkageGroup.toString());


            // gene-clone assignments
            final Map<String, Set<String>> linkageAssignments = assignments.get(linkageGroup);


            // assignment element
            for (final String gene : linkageAssignments.keySet()) {

                final Element assignment_element = DocumentHelper.createElement("assignment");

                assignment_element.addAttribute("gene", gene);
                assignment_element.addText(
                    linkageAssignments.get(gene).toString().replaceAll("\\[", "").replaceAll(
                        "\\]", "").replaceAll("\\,", ""));
                ch_element.add(assignment_element);
            }

            assignments_element.add(ch_element);
        }

        return assignments_element;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    @Override
    public CommandOutputListener newInstance() {
        return new ProcessComplData_PW();
    }
}
